home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga CD-Sensation: Golden Games
/
Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso
/
Brain Activity
/
Conquest
/
Conquest2.mod
< prev
next >
Wrap
Text File
|
1992-12-20
|
49KB
|
1,829 lines
IMPLEMENTATION MODULE Conquest2;
IMPORT
Conversions,
DosD,DosL,
MLL:MathLibLong,
RN:RandomNumber,
LongRealConversions,
String,
SYSTEM;
PROCEDURE PutStr(a: ARRAY OF CHAR);
VAR
tmp: LONGINT;
BEGIN
tmp:=DosL.Write(rawFile,SYSTEM.ADR(a),String.Length(a));
END PutStr;
PROCEDURE PutCh(c: CHAR);
VAR
tmp: LONGINT;
BEGIN
tmp:=DosL.Write(rawFile,SYSTEM.ADR(c),1);
END PutCh;
PROCEDURE PutInt(n,w: LONGINT);
VAR
str: Line;
err: BOOLEAN;
BEGIN
Conversions.ValToStr(n,FALSE,str,10,w," ",err);
IF NOT err THEN
PutStr(str);
END;
END PutInt;
PROCEDURE PutReal(r: LONGREAL; w,d: LONGINT);
VAR
str: Line;
err: BOOLEAN;
BEGIN
LongRealConversions.RealToStr(r,str,w,d,FALSE,err);
IF NOT err THEN
PutStr(str);
END;
END PutReal;
PROCEDURE SetCursorPos(col,row: IntType);
BEGIN
PutStr("\033["); PutInt(row,0);
PutCh(";"); PutInt(col,0); PutCh("H");
cursor.x:=col;
cursor.y:=row;
END SetCursorPos;
PROCEDURE CursorOff;
BEGIN
PutStr("\x9b\x30\x20\x70"); (* cursor off *)
END CursorOff;
PROCEDURE CursorOn;
BEGIN
PutStr("\x9b\x20\x70");
END CursorOn;
PROCEDURE GetChar(VAR c: CHAR);
VAR
result: CHAR;
tmp: LONGINT;
BEGIN
CursorOn;
tmp:=DosL.Read(rawFile,SYSTEM.ADR(result),1);
CursorOff;
IF result="\r" THEN
result:="\n";
END;
IF result="\t" THEN
result:=" ";
END;
c:=result;
IF (c>="a") AND (c<="z") THEN
c:=CHAR((IntType(c)-IntType("a"))+IntType("A"));
END;
PutCh(c);
IF c="\b" THEN
PutStr(" \b\b");
END;
END GetChar;
PROCEDURE GetLine(VAR iline: Line; VAR ind: IntType; onech: BOOLEAN);
VAR
ch: CHAR;
BEGIN
ind:=1;
REPEAT
GetChar(ch);
IF ch="\b" THEN
(* backspace *)
IF ind>1 THEN
DEC(ind);
IF (ind#1) AND onech THEN
PutStr("\b \b");
DEC(ind);
END;
IF (ind#1) AND (NOT onech) THEN
PutCh(" ");
PutCh(ch);
END;
ELSE
PutCh(" ");
END;
ELSIF ch#"\n" THEN
iline[ind]:=ch;
INC(ind);
IF onech THEN
PutCh(" ");
iline[ind]:=" ";
INC(ind);
END;
END;
UNTIL (ind>=25) OR (ch="\n");
WHILE ind<80 DO
iline[ind]:=" ";
INC(ind);
END;
ind:=1;
END GetLine;
PROCEDURE min(x,y: IntType): IntType;
BEGIN
IF x<y THEN
RETURN x;
ELSE
RETURN y;
END;
END min;
PROCEDURE fmin(a,b: LONGREAL): LONGREAL;
BEGIN
IF a<b THEN
RETURN a;
ELSE
RETURN b;
END;
END fmin;
PROCEDURE ClearScreen;
BEGIN
SetCursorPos(1,1);
PutStr("\x9b\x4a"); (* erase to end of display *)
SetCursorPos(1,1);
END ClearScreen;
PROCEDURE PrintMap;
VAR
i1,i2: IntType;
BEGIN
ClearScreen();
FOR i1:=bdsize TO 1 BY -1 DO
IF (i1=1) OR ((i1 MOD 5)=0) THEN
PutInt(i1,2); PutCh("|");
ELSE
PutStr(" |");
END;
FOR i2:=1 TO bdsize DO
PutCh(CHAR(board[i2][i1].enemy));
PutCh(CHAR(board[i2][i1].star));
PutCh(CHAR(board[i2][i1].tf));
END;
PutStr("|\n");
END;
PutStr(" ");
FOR i1:=1 TO bdsize DO
PutStr("---");
END;
PutStr("\n ");
FOR i1:=1 TO bdsize DO
IF (i1=1) OR ((i1 MOD 5)=0) THEN
PutInt(i1,2); PutCh(" ");
ELSE
PutStr(" ");
END;
END;
PutCh('\n');
SetCursorPos(32,18); PutStr("Turn: "); PutInt(turn,3);
SetCursorPos(32,19); PutStr("Production yr: "); PutInt(prodYear,1);
bottomField:=0;
END PrintMap;
PROCEDURE PrintResearch(field: CHAR);
BEGIN
CASE field OF
|"V": SetCursorPos(53,18);
PutStr("V:"); PutInt(vel[player],2);
IF vel[player]<maxVelocity THEN
PutStr(" res:"); PutInt(velocityResearch[player],5);
PutStr(" need:"); PutInt(velocityRequired[vel[player]+1],5);
ELSE
PutStr(" ");
END;
|"R": SetCursorPos( 53,19);
PutStr("R:"); PutInt(curRange[player],2);
IF curRange[player]<maxRange THEN
PutStr(" res:"); PutInt(rangeResearch[player],5);
PutStr(" need:"); PutInt(rangeRequired[curRange[player]+1],5);
ELSE
PutStr(" ");
END;
|"W": SetCursorPos(53,20);
PutStr("W:"); PutInt(weapons[player],2);
IF weapons[player]<maxWeapons THEN
PutStr(" res:"); PutInt(weaponResearch[player],5);
PutStr(" need:"); PutInt(weaponRequired[weapons[player]+1],5);
ELSE
PutStr(" ");
END;
|ELSE
END;
END PrintResearch;
PROCEDURE ClearLeft;
VAR
i: INTEGER;
BEGIN
FOR i:=19 TO 24 DO
SetCursorPos(1,i);
PutStr(blankLine);
END;
END ClearLeft;
PROCEDURE GetToken(VAR line: Line; VAR index,value: IntType; VAR token: CHAR);
BEGIN
value:=0;
token:=" ";
WHILE (line[index]=" ") AND (index<80) DO
INC(index);
END;
IF index<80 THEN
IF (line[index]<"0") OR (line[index]>"9") THEN
value:=1;
ELSE
WHILE (line[index]>="0") AND (line[index]<="9") DO
value:=10*value+IntType(line[index])-IntType("0");
INC(index);
END;
END;
token:=line[index];
INC(index);
END;
WHILE (line[index]#" ") AND (index<80) DO
INC(index);
END;
WHILE (line[index]=" ") AND (index<80) DO
INC(index);
END;
END GetToken;
PROCEDURE ResearchSummary;
VAR
key: CHAR;
value: IntType;
ind: IntType;
iline: Line;
BEGIN
ClearLeft;
PrintResearch("R");
PrintResearch("V");
PrintResearch("W");
END ResearchSummary;
PROCEDURE NewResearch;
BEGIN
IF weapons[player]-weapons[ENEMY]>1 THEN
enemyResearch:="W";
ELSE
IF curRange[ENEMY]<6 THEN
enemyResearch:="R";
ELSIF vel[ENEMY]<3 THEN
enemyResearch:="V";
ELSE
CASE RN.RND(10) OF
|0..2: enemyResearch:="V";
|3..5: enemyResearch:="R";
|6..9: enemyResearch:="W";
END;
END;
END;
END NewResearch;
PROCEDURE DoResearch(team: Team; field: CHAR; amt: IntType);
BEGIN
CASE field OF
|"W": IF weapons[team]<maxWeapons THEN
weaponResearch[team]:=weaponResearch[team]+amt;
amt:=0;
IF weaponResearch[team]>=weaponRequired[weapons[team]+1] THEN
amt:=weaponResearch[team]-weaponRequired[weapons[team]+1];
INC(weapons[team]);
IF team=ENEMY THEN
NewResearch;
field:=enemyResearch;
END;
weaponResearch[team]:=0;
DoResearch(team,field,amt);
END;
END;
|"R": IF curRange[team]<maxRange THEN
rangeResearch[team]:=rangeResearch[team]+amt;
amt:=0;
IF rangeResearch[team]>=rangeRequired[curRange[team]+1] THEN
amt:=rangeResearch[team]-rangeRequired[curRange[team]+1];
INC(curRange[team]);
IF team=ENEMY THEN
NewResearch;
field:=enemyResearch;
END;
rangeResearch[team]:=0;
DoResearch(team,field,amt);
END;
END;
|"V": IF vel[team]<maxVelocity THEN
velocityResearch[team]:=velocityResearch[team]+amt;
amt:=0;
IF velocityResearch[team]>=velocityRequired[vel[team]+1] THEN
amt:=velocityResearch[team]-velocityRequired[vel[team]+1];
INC(vel[team]);
IF team=ENEMY THEN
NewResearch;
field:=enemyResearch;
END;
velocityResearch[team]:=0;
DoResearch(team,field,amt);
END;
END;
|ELSE PutStr("error in research field ");
PutCh(field);
PutCh("\n");
END;
END DoResearch;
PROCEDURE AnyWarShip(team: Team; starnum: IntType): BOOLEAN;
VAR
any: BOOLEAN;
tfNum: IntType;
BEGIN
any:=FALSE;
IF tfStars[starnum][team]>0 THEN
tfNum:=1;
WHILE (NOT any) AND (tfNum<27) DO
any:=(tf[team][tfNum].dest=starnum) AND
(tf[team][tfNum].eta=0) AND
((tf[team][tfNum].c>0) OR (tf[team][tfNum].b>0));
INC(tfNum);
END;
END;
RETURN any;
END AnyWarShip;
PROCEDURE FindBestPlan(starnum: IntType; VAR size: IntType; VAR team: Team);
VAR
curPlanet: PlanetPtr;
BEGIN
team:=none;
size:=0;
curPlanet:=stars[starnum].firstPlanet;
WHILE curPlanet#NIL DO
IF curPlanet^.capacity>size THEN
size:=curPlanet^.capacity;
team:=curPlanet^.team;
END;
curPlanet:=curPlanet^.next;
END;
END FindBestPlan;
PROCEDURE CheckGameOver;
VAR
dead: ARRAY Team OF BOOLEAN;
quit: BOOLEAN;
total: Attribute;
transports: Attribute;
inhabs: Attribute;
team: Team;
tfnum: IntType;
starnum: IntType;
pplan: PlanetPtr;
BEGIN
quit:=gameOver;
FOR team:=ENEMY TO player DO
transports[team]:=0;
inhabs[team]:=0;
FOR tfnum:=1 TO 26 DO
IF tf[team][tfnum].dest#0 THEN
transports[team]:=transports[team]+tf[team][tfnum].t;
END;
END;
END;
FOR starnum:=1 TO nstars DO
pplan:=stars[starnum].firstPlanet;
WHILE pplan#NIL DO
CASE pplan^.team OF
|player: inhabs[player]:=inhabs[player]+pplan^.iu;
|ENEMY: inhabs[ENEMY] :=inhabs[ENEMY] +pplan^.iu;
|ELSE
END;
pplan:=pplan^.next;
END;
END;
FOR team:=ENEMY TO player DO
total[team]:=inhabs[team]+(transports[team] DIV 2);
dead[team]:=(total[team]=0);
END;
IF (NOT dead[player]) AND (NOT dead[ENEMY]) AND (turn>=40) THEN
dead[ENEMY]:=((total[player] DIV total[ENEMY])>=16);
dead[player]:=((total[ENEMY] DIV total[player])>=16);
END;
gameOver:=dead[player] OR dead[ENEMY] OR (turn>maxTurns) OR quit;
IF gameOver THEN
ClearScreen();
PutStr("*** Game over ***\n\n");
PutStr("Player: Population in transports: ");
PutInt(transports[player],4);
PutStr(" IU's on colonies: ");
PutInt(inhabs[player],4);
PutStr(" TOTAL: ");
PutInt(total[player],4);
PutStr("\n\nEnemy: Population in transports: ");
PutInt(transports[ENEMY],4);
PutStr(" IU's on colonies: ");
PutInt(inhabs[ENEMY],4);
PutStr(" TOTAL: ");
PutInt(total[ENEMY],4);
IF (total[ENEMY]>total[player]) THEN
PutStr("\n\n*** THE ENEMY HAS CONQUERED THE GALAXY ***\n");
ELSIF (total[player]>total[ENEMY]) THEN
PutStr("\n\n*** PLAYER WINS- YOU HAVE SAVED THE GALAXY! ***\n");
ELSE
PutStr("\n\n*** DRAWN ***\n");
END;
END;
END CheckGameOver;
PROCEDURE UpdateBoard(x,y: IntType; option: Option);
VAR
screenX,screenY: IntType;
BEGIN
screenX:=3*x+1;
screenY:=16-y;
CASE option OF
|left: SetCursorPos(screenX,screenY);
PutCh(board[x][y].enemy);
|right: SetCursorPos(screenX+2,screenY);
PutCh(board[x][y].tf);
|both: SetCursorPos(screenX, screenY);
PutCh(board[x][y].enemy);
PutCh(board[x][y].star);
PutCh(board[x][y].tf);
END;
END UpdateBoard;
PROCEDURE ZeroTF(tm: Team; tfNum: IntType);
VAR
x,y,i: IntType;
BEGIN
IF tf[tm][tfNum].dest#0 THEN
x:=tf[tm][tfNum].x;
y:=tf[tm][tfNum].y;
IF tf[tm][tfNum].s+tf[tm][tfNum].t+tf[tm][tfNum].c+tf[tm][tfNum].b=0 THEN
IF tf[tm][tfNum].eta=0 THEN
DEC(tfStars[tf[tm][tfNum].dest][tm]);
END;
tf[tm][tfNum].dest:=0;
IF tm=player THEN
board[x][y].tf:=" ";
FOR i:=1 TO 26 DO
IF (tf[player][i].dest#0) AND (tf[player][i].x=x) AND (tf[player][i].y=y) THEN
IF board[x][y].tf=" " THEN
board[x][y].tf:=CHAR(i+IntType("a")-1);
ELSE
board[x][y].tf:="*";
END;
END;
END;
UpdateBoard(x,y,right);
END;
END;
END;
END ZeroTF;
PROCEDURE ClearField;
VAR
newBottom,y: IntType;
BEGIN
newBottom:=cursor.y-1;
IF newBottom<bottomField THEN
FOR y:=newBottom+1 TO bottomField DO
SetCursorPos(50,y);
PutStr("\x9b\x4b"); (* erase to EOL *)
END;
END;
bottomField:=newBottom;
END ClearField;
PROCEDURE JOWDispTF(num: IntType; name: CHAR);
BEGIN
IF num#0 THEN
PutInt(num,2);
PutCh(name);
ELSE
PutStr(" ");
END;
END JOWDispTF;
PROCEDURE DisplayTF(taskf: TaskForce);
BEGIN
JOWDispTF(taskf.t,"t");
JOWDispTF(taskf.s,"s");
JOWDispTF(taskf.c,"c");
JOWDispTF(taskf.b,"b");
END DisplayTF;
PROCEDURE Pause;
VAR
dummy: CHAR;
BEGIN
SetCursorPos(1,18);
PutStr("Press any key to continue... ");
GetChar(dummy);
END Pause;
PROCEDURE PrintPlanet(p: PlanetPtr; see: BOOLEAN);
BEGIN
IF ((cursor.y>21) AND (cursor.x>=50)) OR (cursor.y>24) THEN
Pause;
ClearField();
SetCursorPos(50,1);
END;
PutInt(p^.number,1); PutCh(":");
PutInt(p^.pSeeCapacity,3); PutStr(" ");
SetCursorPos(cursor.x+6,cursor.y);
DEC(cursor.x,6);
IF p^.pSeeCapacity=0 THEN
PutStr(" Decimated");
ELSIF (p^.team=none) AND see THEN
PutStr(" No colony");
ELSIF p^.team=player THEN
PutCh("("); PutInt(p^.inhabitants,3);
PutCh("/"); PutInt(p^.iu,3); PutCh(")");
IF p^.conquered THEN
PutStr("Con ");
ELSE
PutStr(" ");
END;
IF p^.mb#0 THEN
PutInt(p^.mb,2); PutStr("mb ");
ELSE
PutStr(" ");
END;
IF p^.amb#0 THEN
PutInt(p^.amb,2); PutStr("amb");
END;
ELSIF (p^.team=ENEMY) AND see THEN
PutStr("(*ENEMY*)");
IF see AND p^.conquered THEN
PutStr("Con ");
ELSE
PutStr(" ");
END;
IF p^.underAttack THEN
IF p^.mb#0 THEN
PutInt(p^.mb,2); PutStr("mb ");
ELSE
PutStr(" ");
END;
IF p^.amb#0 THEN
PutInt(p^.amb,2); PutStr("amb");
END;
END;
END;
SetCursorPos(cursor.x,cursor.y+1);
END PrintPlanet;
PROCEDURE PrintStar(stnum: IntType);
VAR
see: BOOLEAN;
i,x,y: IntType;
p: PlanetPtr;
BEGIN
IF (stnum>0) AND (stnum<=nstars) THEN
IF cursor.y+4+tfStars[stnum][player]+tfStars[stnum][ENEMY]>19 THEN
ClearField();
Pause;
SetCursorPos(50,1);
END;
IF stars[stnum].visit[player] THEN
see:=FALSE;
PutStr("----- star "); PutCh(CHAR(stnum+IntType("A")-1));
PutStr(" ----- ");
SetCursorPos(50,cursor.y+1);
x:=stars[stnum].x; y:=stars[stnum].y;
IF tfStars[stnum][player]#0 THEN
see:=TRUE;
FOR i:=1 TO 26 DO
IF (tf[player][i].dest=stnum) AND (tf[player][i].eta=0) THEN
PutStr("TF"); PutCh(CHAR(i+IntType("a")-1));
PutStr(" ");
SetCursorPos(54,cursor.y);
DisplayTF(tf[player][i]);
SetCursorPos(50,cursor.y+1);
END;
END;
END;
IF NOT see THEN
see:=(colStars[stnum][player]#0);
END;
IF see AND (tfStars[stnum][ENEMY]#0) THEN
i:=1;
WHILE (tf[ENEMY][i].eta#0) OR (tf[ENEMY][i].dest#stnum) DO
INC(i);
END;
PutStr("EN: ");
SetCursorPos(54,cursor.y);
DisplayTF(tf[ENEMY][i]);
SetCursorPos(50,cursor.y+1);
END;
p:=stars[stnum].firstPlanet;
IF p=NIL THEN
PutStr(" no useable planets ");
SetCursorPos(50,cursor.y+1);
ELSE
REPEAT
PutCh(" ");
PrintPlanet(p,see);
p:=p^.next;
UNTIL p=NIL;
END
END
END
END PrintStar;
PROCEDURE DisplayForces(ennum,plnum: IntType;
VAR enodds,plodds: LONGREAL;
VAR battle: BOOLEAN);
VAR
enForces,plForces: IntType;
BEGIN
enodds:=0.0;
plodds:=0.0;
ZeroTF(ENEMY,ennum);
ZeroTF(player,plnum);
battle:=TRUE;
IF tf[ENEMY][ennum].dest#0 THEN
enForces:=weapons[ENEMY]*(tf[ENEMY][ennum].c*cruiserGuns+tf[ENEMY][ennum].b*battleShipGuns);
ELSE
battle:=FALSE;
END;
IF tf[player][plnum].dest#0 THEN
plForces:=weapons[player]*(tf[player][plnum].c*cruiserGuns+tf[player][plnum].b*battleShipGuns);
ELSE
battle:=FALSE;
END;
SetCursorPos(50,1);
IF tf[ENEMY][ennum].dest#0 THEN
PrintStar(tf[ENEMY][ennum].dest);
ELSIF tf[player][plnum].dest#0 THEN
PrintStar(tf[player][plnum].dest);
END;
ClearField();
IF (enForces=0) AND (plForces=0) THEN
battle:=FALSE;
END;
IF battle THEN
enodds:=LONGREAL(plForces);
enodds:=enodds/LONGREAL(enForces+tf[ENEMY][ennum].t*transportDefend+
tf[ENEMY][ennum].s*scoutDefend);
enodds:=fmin(14.0,enodds);
enodds:=MLL.exp((MLL.log(0.8))*enodds);
plodds:=LONGREAL(enForces);
plodds:=plodds/LONGREAL(plForces+tf[player][plnum].t*transportDefend+
tf[player][plnum].s*scoutDefend);
plodds:=fmin(14.0,plodds);
plodds:=MLL.exp((MLL.log(0.8))*plodds);
SetCursorPos(1,19);
PutStr("enemy "); PutInt(enForces,6);
IF enForces>0 THEN
PutStr("(weap "); PutInt(weapons[ENEMY],2); PutStr(") ");
ELSE
PutStr(" ");
END;
PutStr("sur: "); PutReal(enodds*100.0,3,0);
SetCursorPos(1,20);
PutStr("player"); PutInt(plForces,6);
IF plForces>0 THEN
PutStr("(weap "); PutInt(weapons[player],2); PutStr(") ");
ELSE
PutStr(" ");
END;
PutStr("sur: "); PutReal(plodds*100.0,3,0);
END;
END DisplayForces;
PROCEDURE OnBoard(x,y: IntType);
VAR
i: IntType;
starnum: IntType;
BEGIN
board[x][y].tf:=" ";
i:=1;
REPEAT
IF (tf[player][i].dest#0) AND (tf[player][i].x=x) AND (tf[player][i].y=y) THEN
IF board[x][y].tf=" " THEN
board[x][y].tf:=CHAR(i+IntType("a")-1);
ELSE
board[x][y].tf:="*";
i:=26;
END;
END;
INC(i);
UNTIL i>26;
IF board[x][y].star#"." THEN
board[x][y].enemy:=" ";
starnum:=(IntType(board[x][y].star)-IntType("A"))+1;
IF colStars[starnum][player]#0 THEN
board[x][y].enemy:="@";
END;
END;
UpdateBoard(x,y,both);
END OnBoard;
PROCEDURE Lose(VAR ships: IntType;
VAR loseNone: BOOLEAN;
typ: CHAR;
percent: LONGREAL);
VAR
i,sleft: IntType;
BEGIN
IF ships>0 THEN
sleft:=ships;
FOR i:=1 TO ships DO
IF LONGREAL(RN.Random())>percent THEN
loseNone:=FALSE;
DEC(sleft);
END;
END;
IF sleft<ships THEN
PutCh(" ");
PutInt(ships-sleft,2);
PutCh(typ);
ships:=sleft;
END;
END;
END Lose;
PROCEDURE FireSalvo( attackTeam: Team;
VAR task: TaskForce;
tfnum: IntType;
planet: PlanetPtr;
firstTime: BOOLEAN);
VAR
bases,attackForces,defendForces: IntType;
aLoseNone,pLoseNone: BOOLEAN;
attackOdds,defendOdds,attackSave,defendSave: LONGREAL;
defendTeam: Team;
BEGIN
SetCursorPos(1,24);
PutStr(blankLine);
IF attackTeam=ENEMY THEN
defendTeam:=player;
ELSE
defendTeam:=ENEMY;
END;
attackForces:=weapons[attackTeam]*(task.c*cruiserGuns+task.b*battleShipGuns);
defendForces:=weapons[defendTeam]*(planet^.mb*cruiserGuns+planet^.amb*battleShipGuns);
IF defendForces>0 THEN
attackOdds:=fmin(LONGREAL(defendForces)/LONGREAL(attackForces),14.0);
attackSave:=MLL.exp(MLL.log(0.8)*attackOdds);
defendOdds:=fmin(LONGREAL(attackForces)/LONGREAL(defendForces),14.0);
defendSave:=MLL.exp(MLL.log(0.8)*defendOdds);
SetCursorPos(1,20);
IF attackTeam=player THEN
PutStr("TF"); PutCh(CHAR(tfnum+IntType("a")-1));
ELSE
PutStr("ENE");
END;
PutStr(":"); PutInt(attackForces,5);
PutStr("(weap "); PutInt(weapons[attackTeam],2);
PutStr(")sur: "); PutReal(attackSave*100.0,4,0);
SetCursorPos(1,21);
PutCh(" ");
PutCh(CHAR(planet^.pstar+IntType("A")-1)); PutInt(planet^.number,1);
PutCh(":"); PutInt(defendForces,5);
PutStr("(weap "); PutInt(weapons[defendTeam],2);
PutStr(")sur: "); PutReal(defendSave*100.0,4,0);
SetCursorPos(1,22); PutStr("Attacker losses: ");
SetCursorPos(1,23); PutStr("Planet losses : ");
aLoseNone:=TRUE;
pLoseNone:=TRUE;
REPEAT
SetCursorPos(18,22);
Lose(task.c,aLoseNone,"c",attackSave);
Lose(task.b,aLoseNone,"b",attackSave);
bases:=planet^.mb;
SetCursorPos(18,23);
Lose(planet^.mb,pLoseNone,"m",defendSave);
IF planet^.mb#bases THEN
PutStr("b");
END;
bases:=planet^.amb;
Lose(planet^.amb,pLoseNone,"a",defendSave);
IF planet^.amb#bases THEN
PutStr("mb");
END;
UNTIL NOT ((NOT firstTime) AND pLoseNone AND aLoseNone);
IF aLoseNone THEN
SetCursorPos(18,22);
PutStr("(none)");
END;
IF pLoseNone THEN
SetCursorPos(18,23);
PutStr("(none)");
END;
END;
IF (planet^.mb+planet^.amb=0) AND AnyWarShip(attackTeam,planet^.pstar) THEN
SetCursorPos(1,24);
PutStr("Planet "); PutInt(planet^.number,1);
PutStr("falls! ");
planet^.team:=attackTeam;
planet^.eSeeTeam:=attackTeam;
planet^.conquered:=TRUE;
DEC(colStars[task.dest][defendTeam]);
INC(colStars[task.dest][attackTeam]);
SetCursorPos(50,1);
PrintStar(planet^.pstar);
ClearField();
OnBoard(stars[task.dest].x,stars[task.dest].y);
END;
END FireSalvo;
PROCEDURE Revolt(starnum: IntType);
VAR
pplanet: PlanetPtr;
loses,getsBack: Team;
BEGIN
pplanet:=stars[starnum].firstPlanet;
IF colStars[starnum][ENEMY]+colStars[starnum][player]>0 THEN
WHILE pplanet#NIL DO
IF pplanet^.conquered THEN
IF (pplanet^.team=player) AND (NOT AnyWarShip(player,starnum)) THEN
loses:=player;
getsBack:=ENEMY;
ELSIF (pplanet^.team=ENEMY) AND (NOT AnyWarShip(ENEMY,starnum)) THEN
loses:=ENEMY;
getsBack:=player;
ELSE
loses:=none;
END;
IF loses#none THEN
DEC(colStars[starnum][loses]);
INC(colStars[starnum][getsBack]);
pplanet^.team:=getsBack;
pplanet^.conquered:=FALSE;
pplanet^.pSeeCapacity:=pplanet^.capacity;
OnBoard(stars[starnum].x,stars[starnum].y);
END;
END;
pplanet:=pplanet^.next;
END;
END;
END Revolt;
PROCEDURE EnemyAttack(starnum: IntType);
VAR
attackFact,defenseFact: IntType;
odds,bestScore: LONGREAL;
pplanet,bestPlanet: PlanetPtr;
enTF,i: IntType;
first: ARRAY[0..8] OF BOOLEAN;
BEGIN
FOR i:=1 TO 7 DO
first[i]:=TRUE;
END;
enTF:=1;
WHILE (tf[ENEMY][enTF].dest#starnum) OR (tf[ENEMY][enTF].eta#0) DO
INC(enTF);
END;
REPEAT
attackFact:=tf[ENEMY][enTF].c+6*tf[ENEMY][enTF].b;
bestPlanet:=NIL;
bestScore:=1000.0;
pplanet:=stars[starnum].firstPlanet;
WHILE pplanet#NIL DO
IF pplanet^.team=player THEN
defenseFact:=pplanet^.eSeeDefend;
odds:=LONGREAL(defenseFact)/LONGREAL(attackFact);
IF pplanet^.capacity>30 THEN
odds:=(odds-2.0)*LONGREAL(pplanet^.capacity);
ELSE
odds:=(odds-1.5)*LONGREAL(pplanet^.capacity);
END;
IF odds<bestScore THEN
bestScore:=odds;
bestPlanet:=pplanet;
END;
END;
pplanet:=pplanet^.next;
END;
IF bestScore<0.0 THEN
ClearLeft();
SetCursorPos(1,19);
PutStr("Enemy attacks: ");
PutCh(CHAR(starnum+IntType("A")-1));
PutInt(bestPlanet^.number,1);
SetCursorPos(50,1);
PrintStar(starnum);
ClearField();
Pause;
FireSalvo(ENEMY,tf[ENEMY][enTF],0,bestPlanet,first[bestPlanet^.number]);
first[bestPlanet^.number]:=FALSE;
ZeroTF(ENEMY,enTF);
bestPlanet^.eSeeDefend:=bestPlanet^.mb+6*bestPlanet^.amb;
Pause;
END;
UNTIL (bestScore>=0.0) OR (NOT AnyWarShip(ENEMY,starnum));
Revolt(starnum);
END EnemyAttack;
PROCEDURE GetTF(tm: Team; VAR i: IntType; starnum: IntType);
BEGIN
i:=1;
WHILE (tf[tm][i].dest#0) AND (i<27) DO
INC(i);
END;
IF i=27 THEN
i:=0;
ELSE
tf[tm][i].s:=0;
tf[tm][i].t:=0;
tf[tm][i].c:=0;
tf[tm][i].b:=0;
tf[tm][i].eta:=0;
tf[tm][i].x:=stars[starnum].x;
tf[tm][i].y:=stars[starnum].y;
tf[tm][i].xf:=tf[tm][i].x;
tf[tm][i].yf:=tf[tm][i].y;
tf[tm][i].dest:=starnum;
tf[tm][i].origeta:=0;
tf[tm][i].blasting:=FALSE;
END;
END GetTF;
PROCEDURE JoinSilent(team: Team; VAR parent,child: TaskForce);
BEGIN
parent.t:=parent.t+child.t;
parent.s:=parent.s+child.s;
parent.c:=parent.c+child.c;
parent.b:=parent.b+child.b;
IF (parent.dest#0) AND (child.dest#0) THEN
DEC(tfStars[parent.dest][team]);
END;
child.dest:=0;
END JoinSilent;
PROCEDURE ErrorMessage;
BEGIN
SetCursorPos(1,24);
END ErrorMessage;
PROCEDURE PlayerSalvo(starnum: IntType; VAR battle: BOOLEAN);
VAR
tfCh,plCh: CHAR;
plNum,tfNum: IntType;
found: BOOLEAN;
pl: PlanetPtr;
first: BOOLEAN;
BEGIN
PutStr("Attack planet ");
pl:=stars[starnum].firstPlanet;
IF (colStars[starnum][ENEMY]>1) THEN
PutStr(":");
GetChar(plCh);
ClearLeft();
plNum:=IntType(plCh)-IntType("0");
found:=FALSE;
WHILE NOT found DO
IF pl^.number=plNum THEN
found:=TRUE;
ELSE
IF pl^.next=NIL THEN
found:=TRUE;
ELSE
pl:=pl^.next;
END;
END;
END;
IF pl^.number#plNum THEN
plNum:=0;
ErrorMessage();
PutStr("!that is not a useable planet");
ELSIF pl^.team#ENEMY THEN
ErrorMessage();
PutStr("!that is not an enemy colony");
plNum:=0;
END;
ELSE
WHILE pl^.team#ENEMY DO
pl:=pl^.next;
END;
PutInt(pl^.number,1);
ClearLeft();
plNum:=pl^.number;
END;
IF plNum#0 THEN
SetCursorPos(1,19); PutStr(" attacking tf ");
IF tfStars[starnum][player]>1 THEN
PutStr(":");
GetChar(tfCh);
tfNum:=IntType(tfCh)-IntType("A")+1;
ELSE
tfNum:=1;
WHILE (tf[player][tfNum].dest#starnum) OR (tf[player][tfNum].eta#0) DO
INC(tfNum);
END;
PutCh(CHAR(tfNum+IntType("a")-1));
END;
IF (tfNum<1) OR (tfNum>26) THEN
ErrorMessage();
PutStr(" !illegal tf");
ELSIF tf[player][tfNum].dest=0 THEN
ErrorMessage();
PutStr(" !nonexistant tf");
ELSIF (tf[player][tfNum].dest#starnum) OR (tf[player][tfNum].eta#0) THEN
ErrorMessage();
PutStr(" !tf is not at this star ");
ELSIF tf[player][tfNum].b+tf[player][tfNum].c=0 THEN
ErrorMessage();
PutStr(" !tf has no warships");
ELSE
first:=NOT pl^.underAttack;
IF first THEN
pl^.underAttack:=TRUE;
SetCursorPos(50,1);
PrintStar(starnum);
ClearField();
END;
FireSalvo(player,tf[player][tfNum],tfNum,pl,first);
ZeroTF(player,tfNum);
battle:=(colStars[starnum][ENEMY]>0) AND (AnyWarShip(player,starnum));
END;
END;
END PlayerSalvo;
PROCEDURE PrintColony;
VAR
i: IntType;
pplanet: PlanetPtr;
BEGIN
PutStr("olonies:");
SetCursorPos(50,1);
FOR i:=1 TO nstars DO
pplanet:=stars[i].firstPlanet;
WHILE pplanet#NIL DO
IF pplanet^.team=player THEN
PutCh(CHAR(i+IntType("A")-1));
PrintPlanet(pplanet,TRUE);
END;
pplanet:=pplanet^.next;
END;
END;
ClearField();
ClearLeft();
END PrintColony;
PROCEDURE StarSummary;
VAR
iline: Line;
ind,i,value: IntType;
strs: CHAR;
BEGIN
PutStr("tar summary:");
ClearLeft();
SetCursorPos(1,19);
PutCh(':');
GetLine(iline,ind,TRUE);
GetToken(iline,ind,value,strs);
SetCursorPos(50,1);
IF strs=" " THEN
FOR i:=1 TO nstars DO
PrintStar(i);
END;
ELSE
REPEAT
i:=IntType(strs)-IntType("A")+1;
PrintStar(i);
GetToken(iline,ind,value,strs);
UNTIL strs=" ";
END;
ClearField();
END StarSummary;
PROCEDURE PrintTF(i: IntType);
VAR
x,y: IntType;
BEGIN
IF (i>0) AND (i<=26) THEN
IF tf[player][i].dest#0 THEN
PutStr("TF"); PutCh(CHAR(i+IntType("a")-1)); PutCh(":");
x:=tf[player][i].x; y:=tf[player][i].y;
IF tf[player][i].eta=0 THEN
PutCh(CHAR(tf[player][i].dest+IntType("A")-1));
ELSE
PutCh(" ");
END;
PutCh("("); PutInt(x,2);
PutCh(","); PutInt(y,2);
PutStr(") ");
SetCursorPos(cursor.x+14,cursor.y);
cursor.x:=cursor.x-14;
DisplayTF(tf[player][i]);
IF tf[player][i].eta#0 THEN
PutStr("\x9b7m"); (* reverse on *)
PutCh(CHAR(tf[player][i].dest+IntType("A")-1));
PutInt(tf[player][i].eta,0);
PutStr("\x9b0m"); (* back to normal text *)
END;
SetCursorPos(cursor.x,cursor.y+1);
END;
END;
END PrintTF;
PROCEDURE TFSummary;
VAR
i,value: IntType;
tfs: CHAR;
iline: Line;
ind: IntType;
BEGIN
PutStr("f summary :");
GetLine(iline,ind,TRUE);
GetToken(iline,ind,value,tfs);
SetCursorPos(50,1);
IF tfs=" " THEN
FOR i:=1 TO 26 DO
PrintTF(i);
IF cursor.y+3>19 THEN
ClearField();
Pause;
SetCursorPos(50,1);
END;
END;
ELSE
REPEAT
i:=IntType(tfs)-IntType("A")+1;
PrintTF(i);
IF cursor.y+3>19 THEN
ClearField();
Pause;
SetCursorPos(50,1);
END;
GetToken(iline,ind,value,tfs);
UNTIL tfs=" ";
END;
ClearField();
ClearLeft();
END TFSummary;
PROCEDURE Help(which: IntType);
BEGIN
CASE which OF
|0: SetCursorPos(50, 1); PutStr("(B) Build Battlestar 75");
SetCursorPos(50, 2); PutStr("(C) Build Cruiser 16");
SetCursorPos(50, 3); PutStr("(H) Help");
SetCursorPos(50, 4); PutStr("(R) Range Research 1");
SetCursorPos(50, 5); PutStr("(S) Build Scout 6");
SetCursorPos(50, 6); PutStr("(V) Velocity Research 1");
SetCursorPos(50, 7); PutStr("(W) Weapons Research 1");
SetCursorPos(50, 8); PutStr("(>)(M) Redraw Map");
SetCursorPos(50, 9); PutStr("(>)(R) Research summary");
|1: SetCursorPos(50, 1); PutStr("(B) Blast Planet");
SetCursorPos(50, 2); PutStr("(C) Colony summary");
SetCursorPos(50, 3); PutStr("(D) Taskforce Destination");
SetCursorPos(50, 4); PutStr("(G) Go on (done)");
SetCursorPos(50, 5); PutStr("(H) Help");
SetCursorPos(50, 6); PutStr("(J) Join Taskforces");
SetCursorPos(50, 7); PutStr("(L) Land transports");
SetCursorPos(50, 8); PutStr("(M) Redraw Map");
SetCursorPos(50, 9); PutStr("(N) New Taskforce");
SetCursorPos(50,10); PutStr("(Q) Quit");
SetCursorPos(50,11); PutStr("(R) Research summary");
SetCursorPos(50,12); PutStr("(S) Star summary");
SetCursorPos(50,13); PutStr("(T) Taskforce summary");
|2: SetCursorPos(50, 1); PutStr("(C) Colonies");
SetCursorPos(50, 2); PutStr("(G) Go on (done)");
SetCursorPos(50, 3); PutStr("(H) Help");
SetCursorPos(50, 4); PutStr("(M) Redraw Map");
SetCursorPos(50, 5); PutStr("(O) Odds");
SetCursorPos(50, 6); PutStr("(R) Research summary");
SetCursorPos(50, 7); PutStr("(S) Star summary");
SetCursorPos(50, 8); PutStr("(T) Taskforce summary");
SetCursorPos(50, 9); PutStr("(W) Withdraw");
|3: SetCursorPos(50, 1); PutStr("(B) Break off Attack");
SetCursorPos(50, 2); PutStr("(C) Colony summary");
SetCursorPos(50, 3); PutStr("(G) Go on (done)");
SetCursorPos(50, 4); PutStr("(H) Help");
SetCursorPos(50, 5); PutStr("(J) Join Taskforces");
SetCursorPos(50, 6); PutStr("(M) Redraw Map");
SetCursorPos(50, 7); PutStr("(N) New Taskforce");
SetCursorPos(50, 8); PutStr("(R) Research summary");
SetCursorPos(50, 9); PutStr("(S) Star summary");
SetCursorPos(50,10); PutStr("(T) Taskforce summary");
|4: SetCursorPos(50, 1); PutStr("(A) Bld Advanced M. Base 35");
SetCursorPos(50, 2); PutStr("(B) Build Battlestar 70");
SetCursorPos(50, 3); PutStr("(C) Build Cruiser 16");
SetCursorPos(50, 4); PutStr("(H) Help");
SetCursorPos(50, 5); PutStr("(I) Invest 3");
SetCursorPos(50, 6); PutStr("(M) Build Missile Base 8");
SetCursorPos(50, 7); PutStr("(R) Range Research 1");
SetCursorPos(50, 8); PutStr("(S) Build Scout 6");
SetCursorPos(50, 9); PutStr("(T) Build Transport 1");
SetCursorPos(50,10); PutStr("(V) Velocity Research 1");
SetCursorPos(50,11); PutStr("(W) Weapons Research 1");
SetCursorPos(50,12); PutStr("(>)(C) Colony summary");
SetCursorPos(50,13); PutStr("(>)(M) Redraw Map");
SetCursorPos(50,14); PutStr("(>)(R) Research summary");
SetCursorPos(50,15); PutStr("(>)(S) Star summary");
END;
ClearField();
END Help;
PROCEDURE SplitTF(VAR tfNum,newTF: IntType);
VAR
ships: CHAR;
x,y,numShips: IntType;
ind: IntType;
iline: Line;
BEGIN
GetTF(player,newTF,tf[player][tfNum].dest);
INC(tfStars[tf[player][tfNum].dest][player]);
PutStr(" ships: ");
SetCursorPos(9,cursor.y);
GetLine(iline,ind,FALSE);
GetToken(iline,ind,numShips,ships);
IF ships=" " THEN
(* entire fleet *)
tf[player][newTF].s:=tf[player][tfNum].s;
tf[player][newTF].t:=tf[player][tfNum].t;
tf[player][newTF].c:=tf[player][tfNum].c;
tf[player][newTF].b:=tf[player][tfNum].b;
tf[player][tfNum].s:=0;
tf[player][tfNum].t:=0;
tf[player][tfNum].c:=0;
tf[player][tfNum].b:=0;
ELSE
REPEAT
CASE ships OF
|"T": IF tf[player][tfNum].t<numShips THEN
numShips:=tf[player][tfNum].t;
END;
tf[player][tfNum].t:=tf[player][tfNum].t-numShips;
tf[player][newTF].t:=tf[player][newTF].t+numShips;
|"S": IF tf[player][tfNum].s<numShips THEN
numShips:=tf[player][tfNum].s;
END;
tf[player][tfNum].s:=tf[player][tfNum].s-numShips;
tf[player][newTF].s:=tf[player][newTF].s+numShips;
|"C": IF tf[player][tfNum].c<numShips THEN
numShips:=tf[player][tfNum].c;
END;
tf[player][tfNum].c:=tf[player][tfNum].c-numShips;
tf[player][newTF].c:=tf[player][newTF].c+numShips;
|"B": IF tf[player][tfNum].b<numShips THEN
numShips:=tf[player][tfNum].b;
END;
tf[player][tfNum].b:=tf[player][tfNum].b-numShips;
tf[player][newTF].b:=tf[player][newTF].b+numShips;
|ELSE ErrorMessage();
PutStr(" !Illegal field "); PutCh(ships);
END;
GetToken(iline,ind,numShips,ships);
UNTIL ships=" ";
END;
x:=tf[player][tfNum].x;
y:=tf[player][tfNum].y;
ZeroTF(player,tfNum);
ZeroTF(player,newTF);
OnBoard(x,y);
END SplitTF;
PROCEDURE MakeTF;
VAR
tfCh: CHAR;
tfNum: IntType;
error: BOOLEAN;
newTF: IntType;
BEGIN
PutStr("ew tf- from tf: ");
GetChar(tfCh);
ClearLeft();
tfNum:=IntType(tfCh)-IntType("A")+1;
error:=(tfNum<1) OR (tfNum>26);
IF NOT error THEN
error:=(tf[player][tfNum].eta#0) OR (tf[player][tfNum].dest=0);
END;
IF error THEN
ErrorMessage();
PutStr(" !illegal tf");
ELSIF tf[player][tfNum].blasting THEN
error:=TRUE;
ErrorMessage();
PutStr(" !Tf is blasting a planet ");
ELSE
SetCursorPos(1,19);
SplitTF(tfNum,newTF);
SetCursorPos(1,20);
PrintTF(newTF);
SetCursorPos(1,21);
PrintTF(tfNum);
END;
END MakeTF;
PROCEDURE JoinTF;
VAR
tf1,tf2: CHAR;
tf1n,tf2n,ind,value: IntType;
iline: Line;
BEGIN
PutStr("oin tfs:");
ind:=1;
GetLine(iline,ind,TRUE);
ClearLeft();
GetToken(iline,ind,value,tf1);
tf1n:=IntType(tf1)-IntType("A")+1;
IF (tf1n<1) OR (tf1n>26) THEN
ErrorMessage();
PutStr(" !illegal taskforce "); PutCh(tf1);
ELSIF tf[player][tf1n].eta>0 THEN
ErrorMessage();
PutStr(" !tf"); PutCh(tf1); PutStr(" is not in normal space ");
ELSIF tf[player][tf1n].dest=0 THEN
ErrorMessage();
PutStr(" !nonexistant taskforce "); PutCh(tf1);
ELSIF tf[player][tf1n].blasting THEN
ErrorMessage();
PutStr(" !tf"); PutCh(tf1); PutStr(" is blasting a planet ");
ELSE
GetToken(iline,ind,value,tf2);
REPEAT
tf2n:=IntType(tf2)-IntType("A")+1;
IF (tf2n<1) OR (tf2n>26) THEN
ErrorMessage();
PutStr(" !illegal taskforce "); PutCh(tf2);
ELSIF tf2n=tf1n THEN
ErrorMessage();
PutStr(" !duplicate taskforce "); PutCh(tf2);
ELSIF tf[player][tf2n].dest=0 THEN
ErrorMessage();
PutStr(" !nonexistant taskforce "); PutCh(tf2);
ELSIF (tf[player][tf2n].x#tf[player][tf1n].x) OR (tf[player][tf2n].y#tf[player][tf2n].y) THEN
ErrorMessage();
PutStr(" !tf"); PutCh(tf2); PutStr(" bad location");
ELSIF tf[player][tf2n].eta#0 THEN
ErrorMessage();
PutStr(" !tf"); PutCh(tf2); PutStr(" is not in normal space ");
ELSIF tf[player][tf2n].blasting THEN
ErrorMessage();
PutStr(" !tf"); PutCh(tf2); PutStr(" is blasting a planet ");
ELSE
JoinSilent(player,tf[player][tf1n],tf[player][tf2n]);
END;
GetToken(iline,ind,value,tf2);
UNTIL tf2=" ";
OnBoard(tf[player][tf1n].x,tf[player][tf1n].y);
SetCursorPos(1,19);
PrintTF(tf1n);
END;
END JoinTF;
PROCEDURE PlayerAttack(starnum: IntType);
VAR
battle: BOOLEAN;
command: CHAR;
pplanet: PlanetPtr;
BEGIN
battle:=AnyWarShip(player,starnum);
IF battle THEN
SetCursorPos(32,20);
PutStr("Attack at star ");
PutCh(CHAR(starnum+IntType("A")-1));
WHILE battle DO
SetCursorPos(50,1);
PrintStar(starnum);
ClearField();
SetCursorPos(1,18);
PutStr("P? ");
SetCursorPos(4,18);
GetChar(command);
CASE command OF
|"S": StarSummary();
|"M": PrintMap();
|"H": Help(3);
Pause;
|"N": MakeTF();
|"J": JoinTF();
|"C": PrintColony();
|"R": ResearchSummary();
|"T": TFSummary();
|" ",
"G": PlayerSalvo(starnum,battle);
|"B": PutStr("reak off attack");
battle:=FALSE;
|ELSE ClearLeft();
ErrorMessage();
PutStr(" !Illegal command");
END;
END;
pplanet:=stars[starnum].firstPlanet;
WHILE pplanet#NIL DO
pplanet^.underAttack:=FALSE;
pplanet:=pplanet^.next;
END;
SetCursorPos(1,24);
PutStr("Planet attack concluded ");
Revolt(starnum);
END;
END PlayerAttack;
PROCEDURE SetDestination(tfNum: IntType; VAR error: BOOLEAN);
VAR
starNum,minETA: IntType;
istar: CHAR;
r: LONGREAL;
rge,dst: IntType;
fromStar: IntType;
BEGIN
error:=TRUE;
IF (tf[player][tfNum].eta#0) THEN
(* cancel *)
tf[player][tfNum].eta:=0;
fromStar:=IntType(board[tf[player][tfNum].x][tf[player][tfNum].y].star)-IntType("A")+1;
tf[player][tfNum].dest:=fromStar;
INC(tfStars[fromStar][player]);
PutStr("(Cancelling previous orders)");
SetCursorPos(1,cursor.y+1);
END;
error:=TRUE;
PutStr(" to star: ");
SetCursorPos(11,cursor.y);
GetChar(istar);
starNum:=IntType(istar)-IntType("A")+1;
IF (starNum<0) OR (starNum>nstars) THEN
ErrorMessage();
PutStr(" !illegal star");
ELSE
r:=MLL.sqrt(LONGREAL((stars[starNum].x-tf[player][tfNum].x)*(stars[starNum].x-tf[player][tfNum].x)+
(stars[starNum].y-tf[player][tfNum].y)*(stars[starNum].y-tf[player][tfNum].y)));
SetCursorPos(1,cursor.y+1);
PutStr(" distance:"); PutReal(r,5,1);
dst:=IntType(r-0.09999999999+1.0);
IF (dst>curRange[player]) AND
((tf[player][tfNum].b#0) OR (tf[player][tfNum].c#0) OR (tf[player][tfNum].t#0)) THEN
ErrorMessage();
PutStr(" !maximum range is"); PutInt(curRange[player],3);
ELSIF r<0.5 THEN
SetCursorPos(1,cursor.y+1);
PutStr("Tf remains at star");
ELSE
minETA:=((dst-1) DIV vel[player])+1;
SetCursorPos(1,cursor.y+1);
PutStr("ETA in "); PutInt(minETA,0); PutStr(" turns");
DEC(tfStars[tf[player][tfNum].dest][player]);
tf[player][tfNum].dest:=starNum;
tf[player][tfNum].eta:=minETA;
tf[player][tfNum].origeta:=minETA;
tf[player][tfNum].xf:=tf[player][tfNum].x;
tf[player][tfNum].yf:=tf[player][tfNum].y;
error:=FALSE;
END;
END;
END SetDestination;
PROCEDURE WithDraw(starnum,plnum: IntType);
VAR
withnum: IntType;
error: BOOLEAN;
BEGIN
PutStr("ithdraw ");
ClearLeft();
SetCursorPos(1,19);
SplitTF(plnum,withnum);
IF tf[player][withnum].dest#0 THEN
SetCursorPos(1,20);
SetDestination(withnum,error);
IF error THEN
tf[player][plnum].dest:=starnum;
JoinSilent(player,tf[player][plnum],tf[player][withnum]);
tfStars[starnum][player]:=1;
ELSE
tf[player][withnum].withdrew:=TRUE;
END;
END;
END WithDraw;
PROCEDURE GetStars(sStar: IntType; VAR slist: RealStarList; VAR count: IntType);
VAR
starnum: IntType;
BEGIN
count:=0;
FOR starnum:=1 TO nstars DO
IF curRange[ENEMY]>=distance[sStar][starnum] THEN
INC(count);
slist[starnum]:=LONGREAL(distance[sStar][starnum]);
ELSE
slist[starnum]:=0.0;
END;
END;
END GetStars;
PROCEDURE TFBattle(starnum: IntType);
VAR
ennum,plnum: IntType;
enodds,plodds: LONGREAL;
battle: BOOLEAN;
count,newTF,i: IntType;
ch: CHAR;
playerLoss,enemyLoss: BOOLEAN;
size: IntType;
team: Team;
dstar: IntType;
slist: RealStarList;
fin,first: BOOLEAN;
BEGIN
board[stars[starnum].x][stars[starnum].y].enemy:="!";
UpdateBoard(stars[starnum].x,stars[starnum].y,left);
ennum:=1;
WHILE (tf[ENEMY][ennum].dest#starnum) OR (tf[ENEMY][ennum].eta#0) DO
INC(ennum);
END;
plnum:=1;
IF tfStars[starnum][player]>1 THEN
GetTF(player,newTF,starnum);
FOR i:=1 TO 26 DO
IF (tf[player][i].dest=starnum) AND
(tf[player][i].eta=0) AND
(i#newTF) THEN
JoinSilent(player,tf[player][newTF],tf[player][i]);
END;
END;
tfStars[starnum][player]:=1;
plnum:=newTF;
ELSE
WHILE (tf[player][plnum].dest#starnum) OR (tf[player][plnum].eta#0) DO
INC(plnum);
END;
END;
DisplayForces(ennum,plnum,enodds,plodds,battle);
Pause;
first:=TRUE;
WHILE battle DO
SetCursorPos(1,24);
PutStr(blankLine);
playerLoss:=TRUE;
enemyLoss:=TRUE;
SetCursorPos(1,21);
PutStr(" Enemy losses: ");
SetCursorPos(1,22);
PutStr("Player losses: ");
REPEAT
SetCursorPos(16,21);
Lose(tf[ENEMY][ennum].t,enemyLoss,"t",enodds);
Lose(tf[ENEMY][ennum].s,enemyLoss,"s",enodds);
Lose(tf[ENEMY][ennum].c,enemyLoss,"c",enodds);
Lose(tf[ENEMY][ennum].b,enemyLoss,"b",enodds);
SetCursorPos(16,22);
Lose(tf[player][plnum].t,playerLoss,"t",plodds);
Lose(tf[player][plnum].s,playerLoss,"s",plodds);
Lose(tf[player][plnum].c,playerLoss,"c",plodds);
Lose(tf[player][plnum].b,playerLoss,"b",plodds);
UNTIL NOT ((NOT first) AND enemyLoss AND playerLoss);
IF enemyLoss THEN
SetCursorPos(16,21);
PutStr("(none)");
END;
IF playerLoss THEN
SetCursorPos(16,22);
PutStr("(none)");
END;
first:=FALSE;
DisplayForces(ennum,plnum,enodds,plodds,battle);
IF battle THEN
(* withdraw the bad guys *)
GetTF(ENEMY,newTF,starnum);
IF (tf[player][plnum].c>0) OR (tf[player][plnum].b>0) THEN
tf[ENEMY][newTF].t:=tf[ENEMY][ennum].t;
tf[ENEMY][newTF].s:=tf[ENEMY][ennum].s;
FindBestPlan(starnum,size,team);
IF ((enodds<0.7) AND (size<30)) OR
((enodds<0.5) AND (team=player)) OR
((enodds<0.3) AND (size<60)) OR
(enodds < 0.20) THEN
tf[ENEMY][newTF].c:=tf[ENEMY][ennum].c;
tf[ENEMY][newTF].b:=tf[ENEMY][ennum].b;
END;
END;
IF (tf[ENEMY][newTF].t+tf[ENEMY][newTF].s+
tf[ENEMY][newTF].c+tf[ENEMY][newTF].b)>0 THEN
GetStars(starnum,slist,count);
REPEAT
dstar:=RN.RND(nstars)+1;
UNTIL slist[dstar]>0.0;
tf[ENEMY][newTF].dest:=dstar;
tf[ENEMY][newTF].eta:=IntType((slist[dstar]-0.01)/LONGREAL(vel[ENEMY]))+1;
tf[ENEMY][newTF].xf:=stars[starnum].x;
tf[ENEMY][newTF].yf:=stars[starnum].y;
ELSE
tf[ENEMY][newTF].dest:=0;
END;
fin:=FALSE;
REPEAT
SetCursorPos(1,18);
PutStr("B? ");
SetCursorPos(4,18);
GetChar(ch);
CASE ch OF
|"M": PrintMap();
|"H": Help(2);
|"S": StarSummary();
|"T": TFSummary();
|"C": PrintColony();
|"?":
|"R": ResearchSummary();
|"O": DisplayForces(ennum,plnum,enodds,plodds,battle);
|"W": WithDraw(starnum,plnum);
DisplayForces(ennum,plnum,enodds,plodds,battle);
|" ",
"G": fin:=TRUE;
|ELSE PutStr("!illegal command");
END;
UNTIL fin OR (NOT battle);
ZeroTF(ENEMY,newTF);
ZeroTF(player,plnum);
IF tf[ENEMY][newTF].dest#0 THEN
SetCursorPos(1,23);
PutStr("en withdraws");
SetCursorPos(14,23);
DisplayTF(tf[ENEMY][newTF]);
tf[ENEMY][ennum].t:=tf[ENEMY][ennum].t-tf[ENEMY][newTF].t;
tf[ENEMY][ennum].s:=tf[ENEMY][ennum].s-tf[ENEMY][newTF].s;
tf[ENEMY][ennum].c:=tf[ENEMY][ennum].c-tf[ENEMY][newTF].c;
tf[ENEMY][ennum].b:=tf[ENEMY][ennum].b-tf[ENEMY][newTF].b;
ZeroTF(ENEMY,ennum);
DisplayForces(ennum,plnum,enodds,plodds,battle);
END;
END;
END;
ZeroTF(ENEMY,ennum);
ZeroTF(player,plnum);
Revolt(starnum);
OnBoard(stars[starnum].x,stars[starnum].y);
END TFBattle;
END Conquest2.